<!DOCTYPE html>
<html>
<head>
<title>Op-Amp Circuit Diagram</title>
<style>
  body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
  }
  canvas {
    border: 1px solid #ccc;
    background-color: #fff;
  }
</style>
</head>
<body>
<canvas id="circuitCanvas" width="600" height="450"></canvas>
<script>
  const canvas = document.getElementById('circuitCanvas');
  const ctx = canvas.getContext('2d');

  // Style settings
  ctx.strokeStyle = 'black';
  ctx.fillStyle = 'black';
  ctx.lineWidth = 2;
  ctx.font = '16px Arial';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';

  // Helper function to draw a filled dot (node)
  function drawNode(x, y) {
    ctx.beginPath();
    ctx.arc(x, y, 3.5, 0, 2 * Math.PI);
    ctx.fill();
  }

  // Helper function to draw an open circle (terminal)
  function drawTerminal(x, y) {
    ctx.beginPath();
    ctx.arc(x, y, 4, 0, 2 * Math.PI);
    ctx.stroke();
  }
  
  // Helper function for arrows with solid heads
  function drawArrow(x1, y1, x2, y2) {
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
    
    // arrowhead
    const headlen = 10;
    const angle = Math.atan2(y2 - y1, x2 - x1);
    ctx.beginPath();
    ctx.moveTo(x2, y2);
    ctx.lineTo(x2 - headlen * Math.cos(angle - Math.PI / 6), y2 - headlen * Math.sin(angle - Math.PI / 6));
    ctx.lineTo(x2 - headlen * Math.cos(angle + Math.PI / 6), y2 - headlen * Math.sin(angle + Math.PI / 6));
    ctx.closePath();
    ctx.fill();
  }

  // --- Main Drawing ---

  // Ground line
  const groundY = 380;
  ctx.beginPath();
  ctx.moveTo(50, groundY);
  ctx.lineTo(550, groundY);
  ctx.stroke();

  // Ground Symbol
  const groundSymbolX = 450;
  ctx.beginPath();
  ctx.moveTo(groundSymbolX, groundY);
  ctx.lineTo(groundSymbolX, groundY + 10);
  ctx.moveTo(groundSymbolX - 15, groundY + 10);
  ctx.lineTo(groundSymbolX + 15, groundY + 10);
  ctx.moveTo(groundSymbolX - 10, groundY + 17);
  ctx.lineTo(groundSymbolX + 10, groundY + 17);
  ctx.moveTo(groundSymbolX - 5, groundY + 24);
  ctx.lineTo(groundSymbolX + 5, groundY + 24);
  ctx.stroke();
  drawNode(groundSymbolX, groundY);

  // Op-Amp
  const opAmpBaseX = 280;
  const opAmpTipX = 420;
  const opAmpCenterY = 210;
  const opAmpHeight = 100;
  
  // Op-Amp Body (Triangle)
  ctx.beginPath();
  ctx.moveTo(opAmpBaseX, opAmpCenterY - opAmpHeight / 2); // top-left
  ctx.lineTo(opAmpBaseX, opAmpCenterY + opAmpHeight / 2); // bottom-left
  ctx.lineTo(opAmpTipX, opAmpCenterY); // tip
  ctx.closePath();
  ctx.stroke();

  // Op-Amp Inputs
  const invertingY = opAmpCenterY - 25;
  const nonInvertingY = opAmpCenterY + 25;
  const inputNodeX = 180;
  ctx.beginPath();
  ctx.moveTo(inputNodeX, invertingY);
  ctx.lineTo(opAmpBaseX, invertingY);
  ctx.moveTo(inputNodeX - 80, nonInvertingY);
  ctx.lineTo(opAmpBaseX, nonInvertingY);
  ctx.stroke();

  // Op-Amp Output
  const outputNodeX = 490;
  ctx.beginPath();
  ctx.moveTo(opAmpTipX, opAmpCenterY);
  ctx.lineTo(outputNodeX, opAmpCenterY);
  ctx.stroke();
  
  // Op-Amp Symbols (+/-)
  ctx.font = 'bold 24px Arial';
  ctx.fillText('-', opAmpBaseX + 20, invertingY);
  ctx.fillText('+', opAmpBaseX + 20, nonInvertingY + 2);

  // Op-Amp Power
  ctx.font = '16px Arial';
  const pwrSupplyX = opAmpBaseX + 70;
  // +5.0V
  ctx.beginPath();
  ctx.moveTo(pwrSupplyX, opAmpCenterY - opAmpHeight/2);
  ctx.lineTo(pwrSupplyX, opAmpCenterY - opAmpHeight/2 - 20);
  ctx.stroke();
  ctx.fillText('+5.0 V', pwrSupplyX, opAmpCenterY - opAmpHeight/2 - 35);
  // -5.0V
  ctx.beginPath();
  ctx.moveTo(pwrSupplyX, opAmpCenterY + opAmpHeight/2);
  ctx.lineTo(pwrSupplyX, opAmpCenterY + opAmpHeight/2 + 20);
  ctx.stroke();
  ctx.fillText('-5.0 V', pwrSupplyX, opAmpCenterY + opAmpHeight/2 + 35);


  // Resistor R (feedback)
  const feedbackTopY = 80;
  ctx.beginPath();
  ctx.moveTo(inputNodeX, invertingY);
  ctx.lineTo(inputNodeX, feedbackTopY);
  ctx.lineTo(outputNodeX, feedbackTopY);
  ctx.lineTo(outputNodeX, opAmpCenterY);
  ctx.stroke();
  // Resistor R box
  const resR_x = inputNodeX + 115;
  const resR_w = 80;
  ctx.fillStyle = 'white'; // Erase line under resistor
  ctx.fillRect(resR_x, feedbackTopY - 10, resR_w, 20);
  ctx.fillStyle = 'black';
  ctx.strokeRect(resR_x, feedbackTopY - 10, resR_w, 20);
  ctx.fillText('R', resR_x + resR_w / 2, feedbackTopY - 25);
  
  // Resistor 800 Ohm
  const r800_w = 20;
  const r800_h = 60;
  const r800_y = invertingY + 70;
  ctx.beginPath();
  ctx.moveTo(inputNodeX, invertingY);
  ctx.lineTo(inputNodeX, groundY);
  ctx.stroke();
  // Resistor 800 Ohm box
  ctx.fillStyle = 'white';
  ctx.fillRect(inputNodeX - r800_w/2, r800_y, r800_w, r800_h);
  ctx.fillStyle = 'black';
  ctx.strokeRect(inputNodeX - r800_w/2, r800_y, r800_w, r800_h);
  ctx.textAlign = 'left';
  ctx.fillText('800 \u03A9', inputNodeX + 15, r800_y + r800_h/2);

  // Input V_IN
  const vinX = 100;
  drawTerminal(vinX, nonInvertingY);
  drawArrow(vinX-40, groundY, vinX-40, nonInvertingY);
  ctx.textAlign = 'center';
  const vinLabelY = nonInvertingY + (groundY - nonInvertingY)/2;
  ctx.fillText('V', vinX - 60, vinLabelY);
  ctx.font = '12px Arial';
  ctx.fillText('IN', vinX - 52, vinLabelY + 5);
  ctx.font = '16px Arial';

  // Output V_OUT
  const voutX = 550;
  ctx.beginPath();
  ctx.moveTo(outputNodeX, opAmpCenterY);
  ctx.lineTo(voutX, opAmpCenterY);
  ctx.stroke();
  drawTerminal(voutX, opAmpCenterY);
  drawArrow(voutX-30, groundY, voutX-30, opAmpCenterY);
  const voutLabelY = opAmpCenterY + (groundY - opAmpCenterY)/2;
  ctx.fillText('V', voutX + 20, voutLabelY);
  ctx.font = '12px Arial';
  ctx.fillText('OUT', voutX + 28, voutLabelY + 5);
  ctx.font = '16px Arial';

  // Connection Nodes
  drawNode(inputNodeX, invertingY);
  drawNode(inputNodeX, groundY);
  drawNode(outputNodeX, opAmpCenterY);
  
  // Figure Caption
  ctx.textAlign = 'center';
  ctx.fillText('Fig. 8.1', canvas.width / 2, canvas.height - 15);

</script>
</body>
</html>